#include <iostream>
#include <vector>
#include <string>
#include <assert.h>
#include <cstring>

using namespace std;


template<class CONTAINER>
void PrintContainer(const CONTAINER& con)
{
	auto it = con.begin();

	while (it != con.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}


namespace wxd
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		iterator& begin()
		{
			return _start;
		}
		iterator& end()
		{
			return _finish;
		}
		const_iterator begin()const
		{
			return _start;
		}
		const_iterator end()const
		{
			return _finish;
		}
		vector()
		{}
		void swap(vector<T>& tmp)
		{
			std::swap(_start, tmp._start);
			std::swap(_finish, tmp._finish);
			std::swap(_end_of_storage,tmp._end_of_storage);
		}
		vector(const vector<T>& v)
		{
			reserve(v.size());
			for (auto& x : v)
			{
				push_back(x);
			}
		}

		vector<int>& operator=(vector<T> v)
		{

			swap(v);
			return *this;
		}
		~vector()
		{
			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;
		}

	
		vector(size_t n, const T& val)
		{
		
			reserve(n);
			while (n--)
			{
				push_back(val);
			}
		}


		size_t capacity()const
		{
			return _end_of_storage - _start;
		}
		size_t size()const
		{
			return _finish-_start;
		}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				
				T* tmp = new T[n + 1];
				size_t old_size = size();
				
			    memcpy(tmp,_start,size()*sizeof(T));
                //for(size_t i = 0;i < size();i++)
                //{
                //    tmp[i] = _start[i];
                //}

		
				delete[] _start;
			
				_start = tmp;
				_finish = tmp + old_size;
				_end_of_storage = tmp + n;
			}
		}
		T& operator[](size_t pos)
		{
			assert(pos < size());
			return *(_start + pos);
		}

		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return *(_start + pos);
		}
		void push_back(const T& n);
		void insert(iterator pos,const T& val);
		void erase(iterator pos);
		void resize(size_t n,const T& val = T());

	private:
		T* _start = nullptr;
		T* _finish = nullptr;
		T* _end_of_storage = nullptr;
	};

	template<class T>
	void vector<T>::push_back(const T& n)
	{
		if (size() == capacity())
		{
			reserve(size() == 0 ?4:2*capacity());
		}
		*_finish = n;
		_finish++;
	}
	template<class T>
	void vector<T>::insert(iterator pos, const T& val)
	{

		assert(pos <= _finish);
		size_t gap = pos - _start;
		if (size() == capacity())
		{
			reserve(size() == 0 ? 4 : 2 * capacity());
		}
		pos = _start + gap;
		
		for (iterator it = _finish; it >= pos; it--)
		{
			*(it + 1)= *it;
		}
		
		*pos = val;

		_finish++;
	}
	template<class T>
	void vector<T>::erase(iterator pos)
	{
		assert(pos < _finish);

		for (iterator it = pos + 1; it <= _finish; it++)
		{
			*(it - 1) = *it;
		}


		_finish--;
	} 

	template<class T>
	void vector<T>::resize(size_t n, const T& val)
	{
		if (n > size())
		{
			if (n > capacity())
				reserve(n);
			while (size() != n)
			{
				push_back(val);
			}
		}
		else
		{
			_finish = _start + n;
		}
	}


    void TestVector06()
	{
		vector<string> v1(10,"1111111");
		vector<string> v2;
		v2.push_back("111111");
		v2.push_back("222222");
		v2.push_back("333333");
		v2.push_back("444444");
		v2.push_back("555555");
		v2.push_back("666666");
		v2.push_back("777777");
		v2.push_back("888888");
		v2.push_back("999999");
		PrintContainer(v2);
	}
}

    int main()
{
    wxd::TestVector06();
    return 0;
}

